/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}


/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {

	var Chat = __webpack_require__(1);
	var chatwindow = __webpack_require__(35);
	var chatPeer = __webpack_require__(11);
	var imageViewer = __webpack_require__(36);
	var appEvent = __webpack_require__(14);
	var EventTypes = __webpack_require__(16).EventTypes;
	var chatInfo = __webpack_require__(12);
	var api = __webpack_require__(20);
	var RouteStrategy = __webpack_require__(37);

	imageViewer.init();
	chatwindow.ready()
	  .then(function (userId) {
	    var store = chatInfo.target;
	    var chatName = store.storeName;
	    var chat = new Chat(chatInfo.chatId, chatName + '客服');
	    var isNoticeSend = false;
	    chat.ready(function () {
	      chat.chatList.appendNotice('欢迎您的光临，我们将竭诚为您服务。');
	      chat.active();

	      // 如果指定了客服直接路由到该客服
	      if (store.specialService) {
	        chat.setFromSuid(store.specialService.id);
	        chat.chatList.appendNotice('<span style="color:#ff211c">' + store.specialService.nickname + '</span> 已加入会话');
	        isNoticeSend = true;
	        chatPeer.active();
	        return;
	      }

	      var ids = store.services.map(function (service) {
	        return service.id;
	      });

	      api.getOnlineStatus(ids)
	        .then(function (onlineList) {
	          setTimeout(chatPeer.active, 0);
	          var filter = RouteStrategy(store.strategyName);
	          var service = filter(store, onlineList);

	          console.info('当前服务', service);

	          // 未知BUG，消息提醒可能发送多次,手动调整只发送一次
	          if (isNoticeSend) return;

	          if (!service) {
	            chat.chatList.appendNotice('当前客服可能不在线，您可以联系平台客服。');
	            return;
	          }

	          chat.setFromSuid(service.id);

	          if (!service.online) {
	            chat.chatList.appendNotice('当前客服可能不在线，您可以联系平台客服或者给客服留言，客服收到后会第一时间给你回复，谢谢。');
	            return;
	          }

	          chat.chatList.appendNotice('<span style="color:#ff211c">' + service.nickname + '</span> 已加入会话');
	          isNoticeSend = true;
	        });
	    });
	  })
	  .fail(function (err) {
	    console.error('激活当前节点失败', err);
	  });

	$('body').on('set.send.key', function (event, key) {
	  var $content = $('.ipt-content');
	  $content.unbind('keydown');
	  if (key == 'enter') {
	    $('.ipt-content').on('keydown', function (event) {
	      var $input = $(this);
	      var chatId = $input.closest('.im-content').attr('id').substr('chat-'.length);
	      var chat = Chat.getChat(chatId);
	      var all = $input.contents();
	      var ev = event || window.event;
	      var keyCode = ev.keyCode ? ev.keyCode : ev.which;
	      if (keyCode == 13 && !ev.ctrlKey) {
	        ev.preventDefault();
	        chat.sendMessage();
	      } else if ((keyCode == 10 || keyCode == 13) && ev.ctrlKey) {
	        console.log('$all', all);
	        if (!all.length) {
	          $input.append('<br><div><br></div>');
	        } else {
	          $input.append('<div><br></div>');
	        }
	        cursorToEnd($content);
	      }
	    });
	  } else if (key == 'ctrlEnter') {
	    $('.ipt-content').on('keydown', function (event) {
	      var ev = event || window.event;
	      var chatId = $(this).closest('.im-content').attr('id').substr('chat-'.length);
	      var chat = Chat.getChat(chatId);
	      if ((ev.keyCode == 10 || ev.keyCode == 13) && ev.ctrlKey) {
	        chat.sendMessage();
	      }
	    });
	  }
	});

	function cursorToEnd(obj) {
	  if (window.getSelection) {//ie11 10 9 ff safari
	    obj.focus(); //解决ff不获取焦点无法定位问题
	    var range = window.getSelection();//创建range
	    range.selectAllChildren(obj[0]);//range 选择obj下所有子内容
	    range.collapseToEnd();//光标移至最后
	  }
	  else if (document.selection) {//ie10 9 8 7 6 5
	    var range = document.selection.createRange();//创建选择对象
	    //var range = document.body.createTextRange();
	    range.moveToElementText(obj);//range定位到obj
	    range.collapse(false);//光标移至最后
	    range.select();
	  }
	}

	// 当有新消息来时，闪烁标题
	appEvent.addEventListener(EventTypes.RECEIVED_MESSAGE, function (message) {
	  api.getUserInfo(message.from)
	    .then(function (user) {
	      var chat = Chat.getChat(user.storeId);
	      if (chat && chat.fromSuid == user.id && !titleFlip) {
	        console.log('消息开始闪烁...');
	        onMessageTitleFlip();
	        return;
	      }
	      console.log('消息不闪烁：\n消息为', message,'\n用户为', user, '\nchat为', chat, '\ntitleFlip', titleFlip);
	    });
	});

	//标题闪烁
	var titleCount = 0;
	var titles = ['在线客服', '【有新的消息】_在线客服'];
	var titleFlip;
	function onMessageTitleFlip() {
	  titleFlip = setInterval(function () {
	    document.title = titles[titleCount % 2];
	    titleCount++;
	  }, 1000);
	}


	$(document).on('click', function () {
	  console.log('消息停止闪烁...');
	  clearInterval(titleFlip);
	  titleFlip = null;
	  document.title = titles[0];
	});

	// 发送按钮
	$('.im-wrap')
	  .on('click', '.im-send.send-btn', function () {
	    var chatId = $(this).closest('.im-content').attr('id').substr('chat-'.length);
	    var chat = Chat.getChat(chatId);
	    chat.sendMessage();
	  })
	  // 关闭按钮
	  .on('click', '.im-btn-area .close-btn', function () {
	    var chatId = $(this).closest('.im-content').attr('id').substr('chat-'.length);
	    var $tab = $('#tab-chat-' + chatId);
	    if ($tab.prev('.im-title').length) {
	      var previd = $tab.prev('.im-title').last().attr('id');
	      var prevChatId = previd.substr(9);
	      console.log('要激活的tab的groupId', prevChatId);
	      Chat.getChat(prevChatId).active();
	    } else if ($tab.next('.im-title').length) {
	      var nextid = $tab.next('.im-title').first().attr('id');
	      var nextChatId = nextid.substr(9);
	      Chat.getChat(nextChatId).active();
	    }
	    if (!$tab.siblings('.im-title').length) {
	      var leave = confirm('确定要结束当前会话吗？');
	      if (leave) {
	        document.write('窗口无法自动关闭，请自行关闭标签页');
	        window.close();
	      }
	    } else {
	      var chat = Chat.getChat(chatId);
	      chat.close();
	    }
	  })
	  .on('click', '.im-title', function () {
	    var chatId = $(this).attr('id').substr('tab-chat-'.length);
	    var chat = Chat.getChat(chatId);
	    chat.active();
	  })
	  .on('click', '.im-clue-tab .tab-item', function () {
	    $(this).find('.tab-content').removeClass('not-current').addClass('current');
	    $(this).siblings().find('.tab-content').removeClass('current').addClass('not-current');
	    var tabType = $(this).data('tab');
	    var chatId = $('.im-title.spe').attr('id').substr('tab-chat-'.length);
	    var chat = Chat.getChat(chatId);
	    chat.content.clueInfo.clueContent.update(tabType, chatId);

	  });



/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {

	var content = __webpack_require__(2);
	var tabs = __webpack_require__(32);
	var setting = __webpack_require__(34);
	var chatPeer = __webpack_require__(11);
	var appEvent = __webpack_require__(14);
	var EventTypes = __webpack_require__(16).EventTypes;
	var ServiceSwitchStage = __webpack_require__(16).ServiceSwitchStage;
	var CommandTypes = __webpack_require__(16).CommandTypes;
	var webapi = __webpack_require__(20);
	var Meta = __webpack_require__(12);
	var chats = [];
	var msgSendInterval = null;
	var util = __webpack_require__(6);
	module.exports = Chat;

	/**
	 *
	 * @param chatId
	 * @param name
	 * @param type
	 * @param activeType
	 * @constructor
	 */
	function Chat(chatId, name, type, activeType) {
	  this.chatId = chatId;
	  this.name = name;
	  this.type = type;
	  tabs.addTab(chatId, name, type);
	  chats.push(this);

	  getContentInfo(Meta.type, activeType, chatId, function (err, info) {
	    if (err) info = {};
	    var tabType = activeType || Meta.type;
	    this.content = content.create(chatId, type, tabType, info);
	    this.chatList = this.content.chatList;
	    setting.resize();
	    console.log('chats', chats);
	    $('body').trigger('set.send.key', $('.set-send-key input[name=sendKey][checked]').val());
	    this.isReady = true;
	    this.readyCallback && this.readyCallback();
	  }.bind(this));
	}
	Chat.prototype.ready = function (callback) {
	  if (this.isReady) {
	    return callback();
	  }
	  this.readyCallback = callback;
	};

	Chat.prototype.setFromSuid = function (suid) {
	  this.fromSuid = suid;
	  console.log('set from suid', suid);
	};

	Chat.prototype.sendMessage = function () {
	  if (!this.fromSuid) {
	    this.chatList.appendNotice('暂无客服接待，请联系开思客服');
	  }
	  if (chats[0].isConnected) {
	    var chatType = this.type;
	    var chatId = this.chatId;
	    var fromSuid = this.fromSuid;
	    var chatList = this.content.chatList;
	    var $input = $('#chat-' + this.chatId).find('.ipt-content');
	    var $all = $input.contents();
	    if (!$all.length) {
	      return;
	    }
	    var text = '';
	    $all.each(function (index, ele) {
	      //TextNode 文字节点直接添加到text
	      if (ele.nodeType == 3) {
	        text += ele.nodeValue + '\n';
	        return;
	      }

	      var $ele = $(ele);

	      // 如果子节点有图片，则先发送该节点文字，再发图片
	      var $childrenImg = $ele.find('img');
	      if ($childrenImg.length) {
	        text += $ele.text();
	        sendText();
	        $childrenImg.each(function (index, img) {
	          sendImage(img);
	        });
	        return;
	      }

	      // 如果是图片，发送之前的文字，再发图片
	      if (ele.tagName == 'IMG') {
	        sendText();
	        sendImage(ele);
	        return;
	      }

	      // 其它情况取出文字
	      text += $ele.text() + '\n';
	    });

	    // 最后将剩下的文字发送出去
	    sendText();
	    $input.empty();

	    // 将光标移动到最后，解决 edge 浏览器 + 系统自带输入法导致发送一条消息后只能输入字母的BUG
	    if (window.getSelection) {
	      var sel = window.getSelection();
	      var range = document.createRange();
	      range.selectNodeContents($input[0]);
	      range.collapse(false);
	      sel.removeAllRanges();
	      sel.addRange(range);
	    }
	  } else {
	    this.chatList.appendNotice('由于您连续10分钟未发布任何消息，系统已经终止了此次咨询。如需继续咨询，' +
	      '<a href="javascript:location.reload();">请点击此处</a>');
	  }

	  //$input.closest('.im-edit-area')
	  //  .find('.im-edit-tip').html('还可以输入<span class="still-count">' + (350 - $input.text().length) + '</span>字');

	  function sendText() {
	    // 发送文本消息
	    text = decodeURI(encodeURI(text).replace(/%C2%A0/g, '')).trim();
	    if (text) {
	      var msg = {
	        content: text,
	        type: 'text',
	        time: new Date().getTime(),
	        hasPrefix: false,
	        msgId: util.createRandomId()
	      };

	      if (fromSuid) {
	        msg.touid = fromSuid;
	        msg.hasPrefix = false;
	      }

	      chatList.appendMsg(true, msg);
	      chatPeer.sendMessage(msg);
	      text = '';
	    }
	  }

	  function sendImage(img) {
	    var msg = {
	      content: img.src,
	      type: 'image',
	      time: new Date().getTime(),
	      hasPrefix: false,
	      img: img,
	      msgId: util.createRandomId()
	    };

	    if (chatType == 'chat') {
	      msg.touid = chatId;
	    }

	    if (fromSuid) {
	      msg.touid = fromSuid;
	      msg.hasPrefix = false;
	    }

	    chatList.appendMsg(true, msg);
	    chatPeer.sendMessage(msg);
	  }
	};

	/**
	 * 关闭会话
	 */
	Chat.prototype.close = function () {
	  var id = this.chatId;
	  // 倒序，从列表中删除会话
	  for (var i = chats.length - 1; i > -1; i--) {
	    if (chats[i].chatId == id) {
	      chats.splice(i, 1);
	    }
	  }
	  tabs.removeTab(id);
	  this.content.remove();
	};

	/**
	 * 激活会话
	 */
	Chat.prototype.active = function () {
	  tabs.activeTab(this.chatId);
	  this.content.active();
	  //维修厂连接上
	  chats[0].isConnected = true;
	  //第一个chat激活才设定计时器
	  if (chats.length == 1) {
	    //设定计时器
	    createMsgSendInterval();
	  }

	  appEvent.addEventListener(EventTypes.SEND_MESSAGE, function (data) {
	    chats[0].isConnected = true;
	    if (msgSendInterval) {
	      clearInterval(msgSendInterval);
	      msgSendInterval = null;
	    }
	    //设定计时器
	    createMsgSendInterval();
	  });
	};

	Chat.isChatExists = function (chatId) {
	  for (var i = 0; i < chats.length; i++) {
	    if (chats[i].chatId == chatId) {
	      return true;
	    }
	  }
	  return false;
	};

	Chat.getChat = function (chatId) {
	  for (var i = 0, len = chats.length; i < len; i++) {
	    if (chats[i].chatId == chatId) {
	      return chats[i];
	    }
	  }
	  return null;
	};

	Chat.broadCastNotice = function (content, url, type) {
	  for (var i = 0; i < chats.length; i++) {
	    chats[i].chatList.appendNotice(content, url, type);
	  }
	};


	// 接收到消息
	appEvent.addEventListener(EventTypes.RECEIVED_MESSAGE, function (msg) {
	  var currentUserId = chatPeer.currentUserId();
	  console.log('current user id', currentUserId, msg);
	  webapi.getUserInfo(msg.from).then(function (user) {
	    if (currentUserId === msg.from) {
	      return webapi.getUserInfo(msg.to);
	    } else {
	      return user;
	    }
	  }).then(function (user) {
	    msg.nickname = user.nickname;

	    var chat = Chat.getChat(user.storeId);

	    // 只允许当前会话
	    if(!chat || user.id !== chat.fromSuid) {
	      return;
	    }

	    if (msg.type === 'command') {
	      if (!chat) {
	        return;
	      }
	      var data = msg.content;
	      if (data.type === CommandTypes.SWITCH_SERVICE) {
	        if (data.stage === ServiceSwitchStage.SERVICE_SWITCH_REQUEST) {
	          webapi.getUserInfo(data.toServiceId).then(function (serviceUser) {
	            chat.setFromSuid(serviceUser.id);
	            chat.chatList.appendNotice('当前会话已经由 <span style="color:#ff211c">' + user.nickname + '</span> 转接至 <span style="color:#ff211c">' + serviceUser.nickname + '</span> 为您服务');
	            chat.chatList.appendNotice('<span style="color:#ff211c">' + serviceUser.nickname + '</span> 已经加入会话');
	            chatPeer.sendMessage({
	              type: 'command',
	              content: {
	                type: CommandTypes.SWITCH_SERVICE,
	                stage: ServiceSwitchStage.SERVICE_SWITCH_RECEIVED,
	                fromServiceId: msg.from,
	                fromServiceNickname: msg.nickname
	              },
	              touid: data.toServiceId
	            });
	          });
	        } else if (data.stage === ServiceSwitchStage.SERVICE_SWITCH_RESET) {
	          chat.setFromSuid(msg.from);
	          chat.chatList.appendNotice('客服已转接至 <span style="color:#ff211c">' + msg.nickname + '</span>');
	        }
	      }
	      return;
	    }

	    if (!chat) {
	      console.log('会话不存在，建立新的会话', user.storeId || user.id);
	      chat = new Chat(user.storeId, user.storeName || user.nickname || msg.fromSuid, null, 'store');
	      chat.ready(function () {
	        chat.active();
	        appendMsg(msg);
	      });

	      if (msg.from === currentUserId) {
	        chat.setFromSuid(msg.to);
	      } else {
	        chat.setFromSuid(msg.from);
	      }
	      return;
	    }

	    if (!chat.chatList || !chat.chatList.length) { // 如果当前会话没有消息，则更改客服
	      if (msg.from === currentUserId) {
	        chat.setFromSuid(msg.to);
	      } else {
	        chat.setFromSuid(msg.from);
	      }
	      // 切换客服
	      $('#chat-' + user.storeId + ' p:contains(加入会话) span').text(user.nickname);
	    }

	    appendMsg(msg);

	    function appendMsg(msg) {
	      if (msg.from == currentUserId) {
	        chat.chatList.appendMsg(true, msg);
	      } else {
	        chat.chatList.appendMsg(false, msg);
	      }
	    }
	  });
	});

	appEvent.addEventListener(EventTypes.UPDATED_USER_INFO, function (user) {
	  console.log('更新用户信息', user);
	  webapi.getUserInfo(user.uid, function (err, store) {
	    if (err) {
	      return;
	    }
	    // 替换用户名
	    $('#chat-' + store.storeId + ' .im-service .message-owner:contains(' + user.uid + ')').html(user.nickname || user.uid);
	  });
	});

	appEvent.addEventListener(EventTypes.OFFLINE, function (data) {
	  console.log('OFFLINE:broadcast notice', data);
	  Chat.broadCastNotice('您已断开与服务器的连接，<a class="reconnect" href="#">点击重连</a>');
	});


	function makeUrl(tabType, activeChatId) {
	  var url;
	  if (tabType == 'store') {
	    url = '/ec-api/' + tabType + '/' + (activeChatId || Meta.chatId);
	    return url;
	  }
	  url = '/ec-api/' + tabType + '/' + Meta.clueId;
	  return url;
	}

	function getContentInfo(tabType, activeType, activeChatId, callback) {
	  var info = null;
	  var data = {userId: Meta.username};
	  $.ajax({
	    method: 'GET',
	    url: makeUrl(activeType || tabType, activeChatId),
	    data: data,
	    success: function (data) {
	      info = data;
	      callback(null, info);
	    },
	    error: function (error) {
	      console.log(error);
	      callback(error);
	    }
	  });
	}

	function createMsgSendInterval() {
	  //定时器，超过10min不发送消息断开连接
	  msgSendInterval = setInterval(function () {
	    chatPeer.disconnect();
	    chats[0].isConnected = false;
	    chats[0].chatList.appendNotice('由于您连续10分钟未发布任何消息，系统已经终止了此次咨询。如需继续咨询，' +
	      '<a href="javascript:location.reload();">请点击此处</a>');
	    clearInterval(msgSendInterval);
	    msgSendInterval = null;
	  }, 10 * 60 * 1000);
	}


/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var chatList = __webpack_require__(4);
	var editArea = __webpack_require__(17);
	var clueInfo = __webpack_require__(26);
	var recentContacts = __webpack_require__(30);
	/**
	 * 创建聊天窗口
	 * @param chatId
	 * @param type
	 * @param clueType
	 * @param info
	 * @returns {Content}
	 */
	module.exports.create = function (chatId, type, clueType, info) {
	  var $content =  $('<div class="im-content hide">');
	  $content.attr('id', 'chat-' + chatId)
	    .attr('data-type', type);
	  var recent = recentContacts.create($content);
	  var $window = $('<div class="im-chat-window">');
	  var list = chatList.create($window);
	  var area = editArea.create($window);
	  $content.append($window);
	  var clue = clueInfo.create($content, clueType, info);
	  $content.appendTo('.im-wrap');
	  return new Content(chatId, list, area, clue, recent);
	};

	function Content(chatId, list, editArea, clue, recent) {
	  this.chatId = chatId;
	  this.chatList = list;
	  this.editArea = editArea;
	  this.clueInfo = clue;
	  this.recentContacts = recent;
	}

	Content.prototype.active = function () {
	  var id = this.chatId;
	  $('#chat-' + id).removeClass('hide').siblings('.im-content').addClass('hide');
	};

	Content.prototype.remove = function () {
	  $('#chat-' + this.chatId).remove();
	};


/***/ },
/* 3 */
/***/ function(module, exports) {

	module.exports = window.$;

/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var message = __webpack_require__(5);
	var notice = __webpack_require__(9);

	var $listTmp = $('<div class="im-chat-list">');
	module.exports.create = function ($parent) {
	  var $list = $listTmp.clone();
	  $parent.append($list);
	  return new List($list);
	};

	function List($list) {
	  this.$list = $list;
	  this.length = 0;
	}

	/**
	 * 添加消息到消息列表
	 * @param {Boolean} isSelf 是否为自己发送的消息
	 * @param {Object} msg
	 */
	List.prototype.appendMsg = function (isSelf, msg) {
	  console.log('append----------------------');
	  var $list = this.$list;
	  if (msg.msgId && $list.find('#msg-' + msg.msgId).length) {
	    return;
	  }
	  var $msg = message.create(isSelf, msg);
	  if (!$msg) {
	    return;
	  }
	  $list.append($msg);
	  this.length++;
	  this.scrollToBottom();
	};


	List.prototype.appendNotice = function (content, url, type) {
	  console.log('append notice', content, url, type);
	  var $notice = notice.create(content, url, type);
	  var $list = this.$list;
	  $list.append($notice);
	  this.scrollToBottom();
	};

	List.prototype.scrollToBottom = function () {
	  var $list = this.$list;
	  //var totalHeight = 0;
	  //$list.children().each(function (index, ele) {
	  //  totalHeight += $(ele).height();
	  //});
	  var list = document.getElementById('chat-' + window.Meta.chatId).childNodes[0].childNodes[0];
	  // var scrollVal = list.scrollHeight - list.offsetHeight;
	  // $list.animate({scrollTop: scrollVal}, 300);
	};


/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var util = __webpack_require__(6);
	var html = __webpack_require__(8);
	var $msgTmp = $(html);

	/**
	 * 生成消息返回jquery对象
	 * @param {Boolean} isSelf
	 * @param {Object} msg
	 * @param {String} msg.type 消息类型 image|text
	 * @param {String} msg.content 消息内容
	 * @param {String} msg.nickname 昵称
	 * @param {String} msg.fromSuid 短Id
	 * @returns {*}
	 */
	module.exports.create = function (isSelf, msg) {
	  // 如果该消息存在，不处理
	  if (msg.msgId) {
	    if ($('#msg-' + msg.msgId).length) {
	      return null;
	    }
	  }
	  var $msg = $msgTmp.clone();
	  if (msg.msgId) {
	    $msg.attr('id', 'msg-' + msg.msgId);
	  }
	  var timestr = util.formatTime(msg.time, 'yyyy-MM-dd HH:mm:ss');
	  if (!isSelf) {
	    $msg.addClass('im-service');
	    $msg.find('.message-owner').text(msg.nickname || msg.fromSuid);
	    $msg.find('.lm').html('<span></span>');
	    $msg.find('.im-user-pic')
	      .html('<img alt="" src="/webim/img/service/service1.png"><img class="im-user-pic-cap" alt="" src="/WebIM/img/cap.png">');
	  } else {
	    $msg.find('.message-owner').text(Meta.username);
	    $msg.find('.rm').html('<span></span>');
	    $msg.addClass('im-me');
	    $msg.find('.im-user-pic')
	      .html('<img alt="" src="/webim/img/user/user1.png"><img class="im-user-pic-cap" alt="" src="/WebIM/img/cap.png">');
	  }
	  $msg.find('.send-time').text(timestr);

	  if (msg.type == 'image') {
	    var $img = null;
	    if (msg.img) {
	      $img = $(msg.img);
	    } else {
	      $img = $('<img>');
	      $img.attr('src', msg.content);
	    }

	    if (!$img.attr('id')) {
	      $img.attr('id', msg.msgId || util.createRandomId());
	    }

	    $img.css({
	      'max-width': '120px',
	      'height': 'auto',
	      'width': 'auto'
	    });

	    $msg.find('.message-content').append($img);
	    if ($img.attr('data-error')) {
	      $img.attr('src', '#');
	    }
	    else if (!$img.attr('data-uploaded') && !/^http:|^https:/.test($img.attr('src'))) {
	      $msg.find('.message-content').append('<div class="loading">');
	    }
	  } else if (msg.type == 'text') {
	    var text = $.trim(msg.content);
	    console.log('消息text', text);
	    var p = document.createElement('p');
	    //innerText保证不会按html标签解释
	    p.innerText = text;
	    $msg.find('.message-content').append(p);
	  } else {
	    return false;
	  }
	  return $msg;
	};


/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {

	var UUID = __webpack_require__(7);

	/**
	 * 获取文件扩展名
	 * @param {String} path
	 * @returns {String}
	 */
	module.exports.getExtName = function (path) {
	  if (!path) {
	    return '';
	  }
	  var point = path.lastIndexOf('.');
	  if (point < 0 && point == path.length - 1) {
	    return '';
	  }
	  var start = point + 1;
	  return path.substr(start);
	};

	/**
	 * 创建随机ID
	 * @returns {string}
	 */
	module.exports.createRandomId = function () {
	  return UUID.create(4);
	};

	/**
	 * 时间格式化
	 * @param {Number} timestamp 时间戳
	 * @param {String} fmt 格式化
	 * @returns {String}
	 * @example
	 * var time1 = new Date().Format('yyyy-MM-dd');
	 * var time2 = new Date().Format('yyyy-MM-dd HH:mm:ss');
	 */
	module.exports.formatTime = function (timestamp, fmt) {
	  var now = new Date(timestamp);
	  var o = {
	    'M+': now.getMonth() + 1, //月份
	    'd+': now.getDate(), //日
	    'H+': now.getHours(), //小时
	    'm+': now.getMinutes(), //分
	    's+': now.getSeconds(), //秒
	    'q+': Math.floor((now.getMonth() + 3) / 3), //季度
	    'S': now.getMilliseconds() //毫秒
	  };

	  if (/(y+)/.test(fmt)) {
	    fmt = fmt.replace(RegExp.$1, (now.getFullYear() + '').substr(4 - RegExp.$1.length));
	  }

	  for (var k in o) {
	    if (o.hasOwnProperty(k)) {
	      if (new RegExp('(' + k + ')').test(fmt)) {
	        fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
	      }
	    }
	  }
	  return fmt;
	};

	var supportHtml5 = true;
	if (!window.FileReader || !document.createElement('canvas').getContext) {
	  supportHtml5 = false;
	}
	/**
	 * 判断是否支持html5,简单判断，用FileReader和canvas作为依据
	 * @returns {boolean}
	 */
	module.exports.html5Supported = function () {
	  return supportHtml5;
	};

	module.exports.parseQuery = function (url) {
	  var qindex = url.indexOf('?');
	  var search = url.substr(qindex + 1);
	  var query = {};
	  var all = search.split('&');
	  for (var i = 0; i < all.length; i++) {
	    var item = all[i].split('=');
	    var key = item[0];
	    if (key) {
	      query[item[0]] = item[1];
	    }
	  }
	  return query;
	};


/***/ },
/* 7 */
/***/ function(module, exports) {

	/*
	 * UUID-js: A js library to generate and parse UUIDs, TimeUUIDs and generate
	 * TimeUUID based on dates for range selections.
	 * @see http://www.ietf.org/rfc/rfc4122.txt
	 **/

	function UUIDjs() {
	};

	UUIDjs.maxFromBits = function(bits) {
	  return Math.pow(2, bits);
	};

	UUIDjs.limitUI04 = UUIDjs.maxFromBits(4);
	UUIDjs.limitUI06 = UUIDjs.maxFromBits(6);
	UUIDjs.limitUI08 = UUIDjs.maxFromBits(8);
	UUIDjs.limitUI12 = UUIDjs.maxFromBits(12);
	UUIDjs.limitUI14 = UUIDjs.maxFromBits(14);
	UUIDjs.limitUI16 = UUIDjs.maxFromBits(16);
	UUIDjs.limitUI32 = UUIDjs.maxFromBits(32);
	UUIDjs.limitUI40 = UUIDjs.maxFromBits(40);
	UUIDjs.limitUI48 = UUIDjs.maxFromBits(48);

	// Returns a random integer between min and max
	// Using Math.round() will give you a non-uniform distribution!
	// @see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Math/random
	function getRandomInt(min, max) {
	  return Math.floor(Math.random() * (max - min + 1)) + min;
	}

	UUIDjs.randomUI04 = function() {
	  return getRandomInt(0, UUIDjs.limitUI04-1);
	};
	UUIDjs.randomUI06 = function() {
	  return getRandomInt(0, UUIDjs.limitUI06-1);
	};
	UUIDjs.randomUI08 = function() {
	  return getRandomInt(0, UUIDjs.limitUI08-1);
	};
	UUIDjs.randomUI12 = function() {
	  return getRandomInt(0, UUIDjs.limitUI12-1);
	};
	UUIDjs.randomUI14 = function() {
	  return getRandomInt(0, UUIDjs.limitUI14-1);
	};
	UUIDjs.randomUI16 = function() {
	  return getRandomInt(0, UUIDjs.limitUI16-1);
	};
	UUIDjs.randomUI32 = function() {
	  return getRandomInt(0, UUIDjs.limitUI32-1);
	};
	UUIDjs.randomUI40 = function() {
	  return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 40 - 30)) * (1 << 30);
	};
	UUIDjs.randomUI48 = function() {
	  return (0 | Math.random() * (1 << 30)) + (0 | Math.random() * (1 << 48 - 30)) * (1 << 30);
	};

	UUIDjs.paddedString = function(string, length, z) {
	  string = String(string);
	  z = (!z) ? '0' : z;
	  var i = length - string.length;
	  for (; i > 0; i >>>= 1, z += z) {
	    if (i & 1) {
	      string = z + string;
	    }
	  }
	  return string;
	};

	UUIDjs.prototype.fromParts = function(timeLow, timeMid, timeHiAndVersion, clockSeqHiAndReserved, clockSeqLow, node) {
	  this.version = (timeHiAndVersion >> 12) & 0xF;
	  this.hex = UUIDjs.paddedString(timeLow.toString(16), 8)
	             + '-'
	             + UUIDjs.paddedString(timeMid.toString(16), 4)
	             + '-'
	             + UUIDjs.paddedString(timeHiAndVersion.toString(16), 4)
	             + '-'
	             + UUIDjs.paddedString(clockSeqHiAndReserved.toString(16), 2)
	             + UUIDjs.paddedString(clockSeqLow.toString(16), 2)
	             + '-'
	             + UUIDjs.paddedString(node.toString(16), 12);
	  return this;
	};

	UUIDjs.prototype.toString = function() {
	  return this.hex;
	};
	UUIDjs.prototype.toURN = function() {
	  return 'urn:uuid:' + this.hex;
	};

	UUIDjs.prototype.toBytes = function() {
	  var parts = this.hex.split('-');
	  var ints = [];
	  var intPos = 0;
	  for (var i = 0; i < parts.length; i++) {
	    for (var j = 0; j < parts[i].length; j+=2) {
	      ints[intPos++] = parseInt(parts[i].substr(j, 2), 16);
	    }
	  }
	  return ints;
	};

	UUIDjs.prototype.equals = function(uuid) {
	  if (!(uuid instanceof UUID)) {
	    return false;
	  }
	  if (this.hex !== uuid.hex) {
	    return false;
	  }
	  return true;
	};

	UUIDjs.getTimeFieldValues = function(time) {
	  var ts = time - Date.UTC(1582, 9, 15);
	  var hm = ((ts / 0x100000000) * 10000) & 0xFFFFFFF;
	  return { low: ((ts & 0xFFFFFFF) * 10000) % 0x100000000,
	            mid: hm & 0xFFFF, hi: hm >>> 16, timestamp: ts };
	};

	UUIDjs._create4 = function() {
	  return new UUIDjs().fromParts(
	    UUIDjs.randomUI32(),
	    UUIDjs.randomUI16(),
	    0x4000 | UUIDjs.randomUI12(),
	    0x80   | UUIDjs.randomUI06(),
	    UUIDjs.randomUI08(),
	    UUIDjs.randomUI48()
	  );
	};

	UUIDjs._create1 = function() {
	  var now = new Date().getTime();
	  var sequence = UUIDjs.randomUI14();
	  var node = (UUIDjs.randomUI08() | 1) * 0x10000000000 + UUIDjs.randomUI40();
	  var tick = UUIDjs.randomUI04();
	  var timestamp = 0;
	  var timestampRatio = 1/4;

	  if (now != timestamp) {
	    if (now < timestamp) {
	      sequence++;
	    }
	    timestamp = now;
	    tick = UUIDjs.randomUI04();
	  } else if (Math.random() < timestampRatio && tick < 9984) {
	    tick += 1 + UUIDjs.randomUI04();
	  } else {
	    sequence++;
	  }

	  var tf = UUIDjs.getTimeFieldValues(timestamp);
	  var tl = tf.low + tick;
	  var thav = (tf.hi & 0xFFF) | 0x1000;

	  sequence &= 0x3FFF;
	  var cshar = (sequence >>> 8) | 0x80;
	  var csl = sequence & 0xFF;

	  return new UUIDjs().fromParts(tl, tf.mid, thav, cshar, csl, node);
	};

	UUIDjs.create = function(version) {
	  version = version || 4;
	  return this['_create' + version]();
	};

	UUIDjs.fromTime = function(time, last) {
	  last = (!last) ? false : last;
	  var tf = UUIDjs.getTimeFieldValues(time);
	  var tl = tf.low;
	  var thav = (tf.hi & 0xFFF) | 0x1000;  // set version '0001'
	  if (last === false) {
	    return new UUIDjs().fromParts(tl, tf.mid, thav, 0, 0, 0);
	  } else {
	    return new UUIDjs().fromParts(tl, tf.mid, thav, 0x80 | UUIDjs.limitUI06, UUIDjs.limitUI08 - 1, UUIDjs.limitUI48 - 1);
	  }
	};

	UUIDjs.firstFromTime = function(time) {
	  return UUIDjs.fromTime(time, false);
	};
	UUIDjs.lastFromTime = function(time) {
	  return UUIDjs.fromTime(time, true);
	};

	UUIDjs.fromURN = function(strId) {
	  var r, p = /^(?:urn:uuid:|\{)?([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{2})([0-9a-f]{2})-([0-9a-f]{12})(?:\})?$/i;
	  if ((r = p.exec(strId))) {
	    return new UUIDjs().fromParts(parseInt(r[1], 16), parseInt(r[2], 16),
	                            parseInt(r[3], 16), parseInt(r[4], 16),
	                            parseInt(r[5], 16), parseInt(r[6], 16));
	  }
	  return null;
	};

	UUIDjs.fromBytes = function(ints) {
	  if (ints.length < 5) {
	    return null;
	  }
	  var str = '';
	  var pos = 0;
	  var parts = [4, 2, 2, 2, 6];
	  for (var i = 0; i < parts.length; i++) {
	    for (var j = 0; j < parts[i]; j++) {
	      var octet = ints[pos++].toString(16);
	      if (octet.length == 1) {
	        octet = '0' + octet;
	      }
	      str += octet;
	    }
	    if (parts[i] !== 6) {
	      str += '-';
	    }
	  }
	  return UUIDjs.fromURN(str);
	};

	UUIDjs.fromBinary = function(binary) {
	  var ints = [];
	  for (var i = 0; i < binary.length; i++) {
	    ints[i] = binary.charCodeAt(i);
	    if (ints[i] > 255 || ints[i] < 0) {
	      throw new Error('Unexpected byte in binary data.');
	    }
	  }
	  return UUIDjs.fromBytes(ints);
	};

	// Aliases to support legacy code. Do not use these when writing new code as
	// they may be removed in future versions!
	UUIDjs['new'] = function() {
	  return this.create(4);
	};
	UUIDjs.newTS = function() {
	  return this.create(1);
	};

	module.exports = UUIDjs;


/***/ },
/* 8 */
/***/ function(module, exports) {

	module.exports = "<!-- 客服发送的信息 -->\r\n<div class=\"im-item\">\r\n  <div class=\"im-message clearfix\">\r\n    <!-- 客服头像 -->\r\n    <div class=\"im-user-area\">\r\n      <a class=\"im-user-pic\" href=\"javascript:void(0)\"></a>\r\n    </div>\r\n    <!-- 消息泡 -->\r\n    <div class=\"im-message-detail\">\r\n      <table class=\"im-message-table\">\r\n        <tbody>\r\n        <tr>\r\n          <td class=\"lt\"></td>\r\n          <td class=\"ct\"></td>\r\n          <td class=\"rt\"></td>\r\n        </tr>\r\n        <tr>\r\n          <td class=\"lm\"></td>\r\n          <!-- 消息 -->\r\n          <td class=\"cm\">\r\n            <div class=\"message-title\">\r\n              <p class=\"message-owner\"></p>\r\n              <span class=\"send-time\"></span>\r\n            </div>\r\n            <div class=\"message-content\"></div>\r\n          </td>\r\n          <td class=\"rm\"></td>\r\n        </tr>\r\n        <tr>\r\n          <td class=\"lb\"></td>\r\n          <td class=\"cb\"></td>\r\n          <td class=\"rb\"></td>\r\n        </tr>\r\n        </tbody>\r\n      </table>\r\n    </div>\r\n  </div>\r\n</div>\r\n";

/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var html = __webpack_require__(10);
	var chatPeer = __webpack_require__(11);
	var $noticeTmp = $(html);
	module.exports.create = function (content, url, type) {
	  var $notice = $noticeTmp.clone();
	  var msgType = type || '系统消息';
	  var html = '【' + msgType + '】 ' + content;
	  if (url) {
	    html += '<a href="' + url + '" target="_blank"> [查看详情]</a>';
	  }
	  $notice.find('p').html(html);
	  $notice.find('.reconnect').on('click', function () {
	    chatPeer.active(function (err) {
	      var status = '重连成功';
	      if (err) {
	        status = '重连失败';
	      }
	      $notice.find('p').html(status);
	    });
	  });
	  return $notice;
	};


/***/ },
/* 10 */
/***/ function(module, exports) {

	module.exports = "<!-- 系统通知和提醒 -->\r\n<div class=\"im-msg\">\r\n  <i class=\"notice-icon\"></i>\r\n  <p></p>\r\n  <span class=\"msg-corner msg-lt\"></span>\r\n  <span class=\"msg-corner msg-rt\"></span>\r\n  <span class=\"msg-corner msg-lb\"></span>\r\n  <span class=\"msg-corner msg-rb\"></span>\r\n</div>\r\n";

/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {

	var chatInfo = __webpack_require__(12);
	var actions = __webpack_require__(13);
	var $ = __webpack_require__(3);


	module.exports.active = function () {
	  return $.getJSON('/webim/user/get_token').then(function (data) {
	    var rongCloudToken = data.result.rcToken;
	    var defer = $.Deferred();
	    RongIMClient.connect(rongCloudToken, {
	      onSuccess: function (userId) {
	        // 登录成功后从localStorage拉取未读消息
	        setTimeout(function () {
	          var unreadMessages = localStorage.getItem('unread_messages_' + userId);
	          try {
	            unreadMessages = JSON.parse(unreadMessages) || {};
	            var all = [];

	            for (var uid in unreadMessages) {
	              if (unreadMessages[uid]) {
	                all.push(unreadMessages[uid]);
	              }
	            }

	            // 离线消息的命令消息不处理
	            all = all.filter(function (message) {
	              return message.messageType !== 'CommandMessage'
	            });
	            all.forEach(function (message) {
	              receiveRongMessage(message);
	            });
	          } catch (e) {
	            console.log('没有未读消息', e);
	          }
	          localStorage.setItem('unread_messages_' + userId, '');
	        }, 500);
	        console.log('连接成功', userId);
	        defer.resolve(userId);
	      },
	      onTokenIncorrect: function () {
	        defer.reject('连接失败,无效的TOKEN');
	      },
	      onError: function (errorCode) {
	        console.log('连接失败', errorCode);
	        defer.reject(errorCode);
	      }
	    });
	    return defer;
	  });
	};

	module.exports.currentUserId = function () {
	  return RongIMClient.getInstance().getCurrentUserId();
	};

	module.exports.sendMessage = function (msg) {
	  var defer = $.Deferred();
	  console.log('发送消息', msg);
	  var message = null;
	  switch (msg.type) {
	    case 'text':
	      message = new RongIMLib.TextMessage({ content: msg.content, extra: '普通消息' });
	      break;
	    case 'image':
	      message = new RongIMLib.ImageMessage({ content: '', imageUri: msg.content, extra: '普通消息' });
	      break;
	    case 'command':
	      message = new RongIMLib.CommandMessage({ data: msg.content });
	      break;
	    default:
	      defer.reject();
	      break;
	  }

	  //释放发送消息的信号
	  actions.sendMessage(msg);

	  var msgId = msg.msgId;

	  RongIMClient.getInstance().sendMessage(RongIMLib.ConversationType.PRIVATE, msg.touid, message, {
	    // 发送消息成功
	    onSuccess: function (message) {
	      console.info("发送消息成功", message);
	      localStorage.setItem('rong-msg-sent-time', message.sentTime);
	      console.log('msgUID', message.messageUId, $('#msg-' + msgId));
	      $('#msg-' + msgId).attr('id', 'msg-' + message.messageUId);
	      defer.resolve(message);
	    },
	    onError: function (errorCode, message) {
	      console.error('发送消息失败', errorCode, message);
	      defer.reject(errorCode);
	    }
	  });
	  return defer;
	};

	//断开连接
	module.exports.disconnect = function () {
	  RongIMClient.getInstance().logout();
	  window.IMDisconnected = true;
	};


	// 设置连接监听状态 （ status 标识当前连接状态 ）
	// 连接状态监听器
	RongIMClient.setConnectionStatusListener({
	  onChanged: function (status) {
	    console.log('连接状态改变', status);
	    actions.changeConnectionStatus(status);
	    switch (status) {
	      case RongIMLib.ConnectionStatus.CONNECTED:
	        console.log('链接成功');
	        break;
	      case RongIMLib.ConnectionStatus.CONNECTING:
	        console.log('正在链接');
	        break;
	      case RongIMLib.ConnectionStatus.DISCONNECTED:
	        console.log('断开连接');
	        break;
	      case RongIMLib.ConnectionStatus.KICKED_OFFLINE_BY_OTHER_CLIENT:
	        console.log('其他设备登录');
	        break;
	      case RongIMLib.ConnectionStatus.DOMAIN_INCORRECT:
	        console.log('域名不正确');
	        break;
	      case RongIMLib.ConnectionStatus.NETWORK_UNAVAILABLE:
	        console.log('网络不可用， 10秒后重新登录');
	        setTimeout(function () {
	          RongIMClient.reconnect();
	        }, 1000);
	        break;
	    }

	  }
	});

	var messageTypes = {
	  TextMessage: 'text',
	  ImageMessage: 'image',
	  CommandMessage: 'command'
	};

	// 消息监听器
	RongIMClient.setOnReceiveMessageListener({
	  // 接收到的消息
	  onReceived: receiveRongMessage
	});

	function receiveRongMessage(message) {
	  if (message.offLineMessage) {
	    return;
	  }

	  var content = '';
	  var messageType = messageTypes[message.messageType];

	  switch (message.messageType) {
	    case 'TextMessage':
	      content = message.content.content;
	      break;
	    case 'ImageMessage':
	      content = message.content.imageUri || message.content.content;
	      break;
	    case 'CommandMessage':
	      content = message.content && message.content.data;
	      break;
	    default:
	      console.log('其他消息类型，不处理', message);
	      break;
	  }

	  var msg = {
	    type: messageType,
	    content: content,
	    time: message.sentTime,
	    fromSuid: message.senderUserId,
	    from: message.senderUserId,
	    to: message.targetId,
	    msgId: message.messageUId
	  };

	  actions.receivedMessage(msg);
	  console.log('接收到消息', message);
	  localStorage.setItem('rong-msg-sent-time', message.sentTime);
	}


/***/ },
/* 12 */
/***/ function(module, exports) {

	module.exports = window.Meta;


/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {

	var appEvent = __webpack_require__(14);
	var ActionTypes = __webpack_require__(16).EventTypes;

	/**
	 * 触发发送消息事件
	 * @param message
	 */
	module.exports.sendMessage = function (message) {
	  appEvent.fire(ActionTypes.SEND_MESSAGE, message);
	};

	module.exports.changeConnectionStatus = function (status) {
	  appEvent.fire(ActionTypes.CONNECTION_STATUS_CHANGED, status);
	};

	/**
	 * 触发接收消息事件
	 * @param message
	 */
	module.exports.receivedMessage = function (message) {
	  appEvent.fire(ActionTypes.RECEIVED_MESSAGE, message);
	};

	/**
	 * 触发系统通知事件
	 * @param notification
	 */
	module.exports.receivedNotification = function (notification) {
	  appEvent.fire(ActionTypes.RECEIVED_NOTIFICATION, notification);
	};

	/**
	 * 触发用户信息更新事件
	 * @param info
	 */
	module.exports.updatedUserInfo = function (info) {
	  appEvent.fire(ActionTypes.UPDATED_USER_INFO, info);
	};

	/**
	 * 出发离线事件
	 * @param data
	 */
	module.exports.offline = function (data) {
	  appEvent.fire(ActionTypes.OFFLINE, data);
	};

	/**
	 * 触发更新客服列表事件
	 * @param services
	 */
	module.exports.updateServices = function (services) {
	  appEvent.fire(ActionTypes.UPDATED_SERVICES, services);
	};


/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {

	var Event = __webpack_require__(15);
	var appEvent = new Event();
	module.exports = appEvent;


/***/ },
/* 15 */
/***/ function(module, exports) {

	function Event() {
	  this._events = {};
	}

	// 添加事件监听
	Event.prototype.addEventListener = function (type, callback) {
	  if (typeof callback != 'function') {
	    return;
	  }

	  if (!this._events[type]) {
	    this._events[type] = [];
	  }

	  this._events[type].push(callback);
	};

	// 移除事件监听
	Event.prototype.removeEventListener = function (type, callback) {
	  var events = this._events;
	  for (var key in events) {
	    if (!events.hasOwnProperty(key)) continue;
	    if (key === type) {
	      var callbacks = events[key];
	      // 移除指定的监听函数
	      if (callback) {
	        for (var i = callbacks.length - 1; i > -1; i--) {
	          if (callbacks[i] === callback) {
	            callbacks.splice(i, 1);
	          }
	        }
	        // 移除该事件的所有监听函数
	      } else {
	        events[key] = [];
	      }
	    }

	  }
	};

	// 触发事件
	Event.prototype.fire = function (type, data) {
	  var events = this._events;
	  var callbacks = events[type] || [];
	  callbacks.forEach(function (callback) {
	    callback(data);
	  });
	};

	module.exports = Event;


/***/ },
/* 16 */
/***/ function(module, exports) {

	module.exports.EventTypes = keyMirror({
	  SEND_MESSAGE: null,
	  RECEIVED_MESSAGE: null,
	  RECEIVED_NOTIFICATION: null,
	  UPDATED_USER_INFO: null,
	  UPDATED_SERVICES: null,
	  OFFLINE: null,
	  CONNECTION_STATUS_CHANGED: null
	});

	module.exports.StrategyTypes = keyMirror({
	  ONLINE_RANDOM: null
	});

	module.exports.ServiceSwitchStage = keyMirror({
	  SERVICE_SWITCH_REQUEST: null,       // 开始请求切换客服
	  SERVICE_SWITCH_RECEIVED: null,      // 客户端接收到请求
	  SERVICE_SWITCH_SUCCESS: null,        // 切换完毕
	  SERVICE_SWITCH_RESET: null          //重置客服
	});

	module.exports.CommandTypes = keyMirror({
	  SWITCH_SERVICE: null
	});


	module.exports.OnlineStatus = {
	  ONLINE: 0,
	  OFFLINE: 1,
	  LOGOUT: 2
	};

	module.exports.ServiceType = {
	  MAIN_SERVICE: 1,
	  CUSTOMER_SERVICE: 2
	};

	function keyMirror(obj) {
	  for (var key in obj) {
	    if (obj.hasOwnProperty(key)) {
	      if (typeof obj[key] === 'object' && obj[key]) {
	        keyMirror(obj[key]);
	      } else {
	        obj[key] = key;
	      }
	    }
	  }
	  return obj;
	}


/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {

	var toolbar = __webpack_require__(18);
	var input = __webpack_require__(22);
	var footer = __webpack_require__(24);

	module.exports.create = function ($parent) {
	  var $area = $('<div class="im-edit-area">');
	  toolbar.create($area);
	  input.create($area);
	  footer.create($area);
	  $parent.append($area);
	  return $area;
	};


/***/ },
/* 18 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var imagePicker = __webpack_require__(19);
	var chatPeer = __webpack_require__(11);
	var html = __webpack_require__(21);
	var $toolbarTmp = $(html);

	/**
	 * 创建toolbar, 并绑定事件
	 * @returns {*}
	 */
	module.exports.create = function ($parent) {
	  var $toolbar = $toolbarTmp.clone();
	  var $uploadBtn = $toolbar.find('.upload-btn');
	  imagePicker.bind($uploadBtn, function (url) {
	    insertImageAndUpload($uploadBtn, url);
	  });
	  $parent.append($toolbar);
	  return $toolbar;
	};

	/**
	 * 将图片插入到编辑器中并上传
	 * @param $uploadBtn
	 * @param url
	 */
	function insertImageAndUpload($uploadBtn, url) {
	  var $img = $('<img>');
	  $img.css({
	    'max-width': '120px',
	    height: 'auto'
	  });
	  $img.attr('src', url);
	  // $img.attr('id', id);
	  $img.attr('contenteditable', false);
	  $img.attr('oncontrolselect', 'return false;');
	  $uploadBtn.closest('.im-edit-area').find('.ipt-content').append($img);
	}


/***/ },
/* 19 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var util = __webpack_require__(6);
	var api = __webpack_require__(20);
	var queue = [];

	/**
	 * 将回调函数绑定到上传按钮
	 * @param {Element} uploadBtn
	 * @param {Function} callback callback(base64, ext)
	 */
	module.exports.bind = function (uploadBtn, callback) {
	  queue.push([uploadBtn, callback]);
	  bindAll();
	};

	function bindAll() {

	  var pair = queue.shift();

	  if (!pair) {
	    return;
	  }

	  var $btn = $(pair[0]);
	  var callback = pair[1];

	  var fileInput = $btn.find('.upload-file')[0];
	  var $form = $btn.find('form');
	  fileInput.onchange = function () {
	    if (!this.value) {
	      return;
	    }
	    var arr = this.value.split('.');
	    var ext = arr[arr.length - 1];
	    var filename = util.createRandomId() + '.' + ext;
	    console.log('开始上传图片', filename);
	    api.getOssConfig().then(function (conf) {
	      console.log('获取OSS配置文件', conf);
	      $form.attr('action', conf.url);
	      $form.find('input[name="key"]').val(conf.dir + filename);
	      $form.find('input[name="policy"]').val(conf.policy);
	      $form.find('input[name="OSSAccessKeyId"]').val(conf.accessKeyId);
	      $form.find('input[name="success_action_status"]').val('200');
	      $form.find('input[name="signature"]').val(conf.signature);
	      $form.ajaxForm({
	        success: function (data) {
	          console.log('上传成功', data);
	          callback(conf.url + '/' + conf.dir + filename);
	        }
	      });
	      $form.submit();
	      fileInput.value = '';
	    });
	  };

	  bindAll();
	}


/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var actions = __webpack_require__(13);
	var _userCache = {};
	var _userStoreCache = {};
	/**
	 * 获取当前用户信息，如果用户信息不存在，重新获取，返回null,同时触发UPDATED_USER_INFO事件
	 * @param userId
	 * @returns {*}
	 */
	module.exports.getUserInfo = function (userId) {
	  var defer = $.Deferred();
	  console.log('更新用户信息:', userId);
	  if (_userCache[userId]) {
	    defer.resolve(_userCache[userId]);
	  } else {
	    $.get('/webim/user/' + userId).done(function (data) {
	      console.log('获取用户信息成功', data);
	      _userCache[userId] = data.result;
	      defer.resolve(data.result);
	    }).fail(function (err) {
	      console.error('获取用户信息失败', err);
	      defer.reject(err);
	    });
	  }
	  return defer;
	};

	var ossConfigCache = {};
	module.exports.getOssConfig = function () {
	  var defer = $.Deferred();
	  var now = new Date().getTime();
	  if (ossConfigCache.expires && ossConfigCache.expires > now + 10 * 60 * 1000) {
	    defer.resolve(ossConfigCache);
	    return defer;
	  }

	  return $.getJSON('/webim/misc/oss_signature').then(function (result) {
	    ossConfigCache = result;
	    return ossConfigCache;
	  });
	};

	module.exports.getHistoryMessages = function (targetId, timestamp) {
	  $.getJSON('/webim/message/history?target=' + targetId + '&before=' + timestamp || '').then(function (data) {
	    return data.result;
	  });
	};

	/**
	 * 批量获取用户在线状态
	 * @param ids
	 */
	module.exports.getOnlineStatus = function (ids) {
	  var query = ids.map(function (id) {
	    return 'id=' + id;
	  });
	  
	  var expires = new Date().getTime() - 30 * 60 * 1000;
	  query.push('expires=' + expires);

	  var search = query.join('&');
	  return $.getJSON('/webim/user/online_status/batch?' + search).then(function (data) {
	    return data.result;
	  });
	};




/***/ },
/* 21 */
/***/ function(module, exports) {

	module.exports = "<!-- 编辑工具栏 -->\r\n<div class=\"im-toolbar\">\r\n  <div class=\"btn btn-default btn-sm upload-btn\">\r\n    <form method=\"post\">\r\n      <input name=\"key\" hidden>\r\n      <input name=\"policy\" hidden>\r\n      <input name=\"OSSAccessKeyId\" hidden>\r\n      <input name=\"success_action_status\" hidden>\r\n      <input name=\"signature\" hidden>\r\n      <input type=\"file\" class=\"upload-file\" name=\"file\" accept=\"image/gif,image/jpg,image/jpeg,image/png,image/bmp\">\r\n    </form>\r\n  </div>\r\n</div>\r\n";

/***/ },
/* 22 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var chatPeer = __webpack_require__(11);
	var html = __webpack_require__(23);
	var api = __webpack_require__(20);
	var util = __webpack_require__(6);
	var $inputAreaTmp = $(html);
	module.exports.create = function ($parent) {
	  var $inputArea = $inputAreaTmp.clone();
	  var $input = $inputArea.find('.ipt-content');
	  var input = $input[0];

	  input.addEventListener && input.addEventListener('paste', function (event) {
	    var clipboardData = event.clipboardData || window.clipboardData;
	    if (clipboardData) {
	      var items = clipboardData.items;
	      if (!items) return;

	      // 提取图片或文本
	      var item = items[0];
	      var types = clipboardData.types || [];
	      for (var i = 0; i < types.length; i++) {
	        if (types[i] === 'Files') {
	          item = items[i];
	          break;
	        }
	      }
	      // 图片
	      if (item && item.kind === 'file' && item.type.match(/^image\//i)) {
	        var file = item.getAsFile();
	        uploadAndInertImage(file).then(function () {
	          var sel = window.getSelection();
	          var range = document.createRange();
	          range.selectNodeContents(input);
	          range.collapse(false);
	          sel.removeAllRanges();
	          sel.addRange(range);
	        });
	      }
	    }

	    if (item && item.kind === 'string') {
	      item.getAsString(function (str) {
	        $input.append(str);
	        var sel = window.getSelection();
	        var range = document.createRange();
	        range.selectNodeContents(input);
	        range.collapse(false);
	        sel.removeAllRanges();
	        sel.addRange(range);
	      });
	    }

	    event.preventDefault();
	  });
	  $parent.append($inputArea);

	  $input.on('keyup', function () {
	    var len = $(this).text().length;
	    var $tips = $(this).closest('.im-edit-area').find('.im-edit-tip');
	    //if (len <= 350) {
	    //  $tips.html('还可以输入<span class="still-count">' + (350 - len) + '</span>字');
	    //  return;
	    //}
	    //$tips.html('您输入的文字已经超过<span class="still-count">' + (len - 350) + '</span>字');
	    $tips.html('您已输入<span class="still-count">' + len+ '</span>个字');
	  });

	  function uploadAndInertImage(file) {
	    var ext = file.type.split('/')[1];
	    var filename = util.createRandomId() + '.' + ext;
	    var url = '';
	    return api.getOssConfig().then(function (conf) {
	      var filepath = conf.dir + filename;
	      var formData = new FormData();
	      formData.append('key', filepath);
	      formData.append('policy', conf.policy);
	      formData.append('OSSAccessKeyId', conf.accessKeyId);
	      formData.append('success_action_status', '200');
	      formData.append('signature', conf.signature);
	      formData.append('file', file);
	      url = conf.url + '/' + filepath;
	      return $.ajax({
	        url: conf.url,
	        data: formData,
	        cache: false,
	        contentType: false,
	        processData: false,
	        type: 'POST'
	      });
	    }).then(function () {
	      console.log('上传图片成功', url);
	      var $img = $('<img>');
	      $img.css({
	        'max-width': '120px',
	        height: 'auto'
	      });
	      $img.attr('src', url);
	      $img.attr('contenteditable', false);
	      $img.attr('oncontrolselect', 'return false;');
	      $input.append($img);
	    });
	  }

	};



/***/ },
/* 23 */
/***/ function(module, exports) {

	module.exports = "<div class=\"im-ipt-area\">\r\n  <div class=\"im-ipt ipt-content\" contenteditable=\"true\"></div>\r\n</div>\r\n";

/***/ },
/* 24 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var $footerTmp = $(__webpack_require__(25));
	module.exports.create = function ($parent) {
	  var $footer = $footerTmp.clone();
	  var sendKey = $('body .set-send-key input[name=sendKey][checked]').val();
	  if (sendKey == 'ctrlEnter') {
	    $('.ctrl-enter-key').find('i').removeClass('im-icon-right').addClass('im-icon-check');
	    $('.enter-key').find('i').removeClass('im-icon-check').addClass('im-icon-right');
	  }
	  limitInput($footer);
	  changeSendKey($footer);
	  $parent.append($footer);
	  return $footer;
	};

	function limitInput($footer) {
	  $footer.closest('.im-edit-area').find('.ipt-content').on('keyup', function () {
	    var len = $(this).text().length;
	    if (len <= 350) {
	      $footer.find('.im-edit-tip').html('还可以输入<span class="still-count">' + (350 - len) + '</span>字');
	      return;
	    }
	    $footer.find('.im-edit-tip').html('您输入的文字已经超过<span class="still-count">' + (len - 350) + '</span>字');
	  });
	}

	// 切换发送按钮快捷键
	function changeSendKey($footer) {
	  $footer.find('.set-send-btn').on('click', function () {
	    var $setKey = $footer.find('.set-send-key');
	    if ($setKey.css('display') == 'none') {
	      $setKey.css({'display': 'block'});
	    } else {
	      $setKey.css({'display': 'none'});
	    }
	    return false;
	  });

	  $footer.find('.set-send-label').on('click', function () {
	    var $enter = $('.enter-key');
	    var $ctrlEnter = $('.ctrl-enter-key');
	    if ($(this).hasClass('enter-key')) {
	      $enter.find('i').removeClass('im-icon-right').addClass('im-icon-check');
	      $ctrlEnter.find('i').removeClass('im-icon-check').addClass('im-icon-right');
	    } else {
	      $ctrlEnter.find('i').removeClass('im-icon-right').addClass('im-icon-check');
	      $enter.find('i').removeClass('im-icon-check').addClass('im-icon-right');
	    }
	    var $currentRadio = $(this).find('input[type=radio]');
	    $currentRadio.attr('checked', true);
	    $('body').trigger('set.send.key', $currentRadio.val());
	    $footer.find('.set-send-key').hide();
	  });
	}


/***/ },
/* 25 */
/***/ function(module, exports) {

	module.exports = "<!-- 按钮区 -->\n<div class=\"im-btn-area\">\n  <!-- 发送按钮 -->\n  <div class=\"im-send-btn-area\">\n    <a class=\"im-send send-btn\" href=\"javascript:void(0);\" title=\"点击发送消息\">发送</a>\n    <a class=\"im-send set-send-btn\" href=\"javascript:void(0);\">\n      <i class=\"glyphicon glyphicon-triangle-bottom\"></i>\n    </a>\n    <div class=\"set-send-key\" id=\"set-key\">\n      <form>\n        <label class=\"set-send-label enter-key\">\n          <input type=\"radio\" name=\"sendKey\" value=\"enter\" checked>\n          <a href=\"javascript:void(0)\">\n            <i class=\"im-icon-check\"></i>\n            <span>按Enter键发送消息，Ctrl+Enter换行</span>\n          </a>\n        </label>\n        <label class=\"set-send-label ctrl-enter-key\">\n          <input type=\"radio\" name=\"sendKey\" value=\"ctrlEnter\">\n          <a href=\"javascript:void(0)\">\n            <i class=\"im-icon-right\"></i>\n            <span>按Ctrl+Enter键发送消息，Enter换行</span>\n          </a>\n        </label>\n      </form>\n    </div>\n  </div>\n  <!-- 关闭按钮 -->\n  <a class=\"close-btn\" href=\"javascript:void(0);\">关闭</a>\n  <!-- 提示文字数 -->\n  <div class=\"im-edit-tip\">\n    您已输入<span class=\"still-count\">0</span>个字\n  </div>\n</div>\n";

/***/ },
/* 26 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var html = __webpack_require__(27);
	var clueTabs = __webpack_require__(28);
	var clueContent = __webpack_require__(29);
	var $clueInfoTmp = $(html);

	/**
	 *
	 * @param $parent,父容器
	 * @param activeType,供应商主动找维修厂,activeType='store'
	 * @param tabType
	 * @param info
	 * @returns {ClueInfo}
	 */
	exports.create = function ($parent, tabType, info) {
	  var $clueInfo = $clueInfoTmp.clone();
	  //在线索信息栏添加tabs
	  var $clueTabs = clueTabs.create($clueInfo.find('ul.im-clue-tab'), tabType);
	  var $clueContent = clueContent.create($clueInfo.find('.im-clue-content'), tabType, info);
	  $parent.append($clueInfo);
	  return new ClueInfo($clueTabs, $clueContent);
	};

	function ClueInfo(clueTabs, clueContent) {
	  this.clueTabs = clueTabs;
	  this.clueContent = clueContent;
	}



/***/ },
/* 27 */
/***/ function(module, exports) {

	module.exports = "<div class=\"im-clue-info\">\r\n  <ul class=\"im-clue-tab\">\r\n\r\n  </ul>\r\n  <div class=\"im-clue-content\">\r\n    <div class=\"loading-icon\"></div>\r\n  </div>\r\n  <!-- 常见问题 -->\r\n  <!--<div class=\"im-problem-box\">-->\r\n  <!--<div class=\"im-problem-bar\">常见问题</div>-->\r\n  <!--<div class=\"im-problem-content\"><p>暂无数据</p></div>-->\r\n  <!--</div>-->\r\n</div>\r\n";

/***/ },
/* 28 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Created by Administrator on 2016/8/5.
	 */
	var $ = __webpack_require__(3);
	var Meta = __webpack_require__(12);
	var type = Meta.type;

	exports.create = function ($parent, tabType) {
	  console.log('Meta类型', type);
	  var $clueTabs = createTabs(tabType || type);
	  $parent.append($clueTabs);
	  return $clueTabs;
	};


	function createTabs(clueType) {
	  var $html;
	  switch (clueType) {
	    case 'inquiry':
	      $html = $('<li class="col-xs-4 tab-item" data-tab="inquiry">' +
	        '<div class="tab-content current">询价单信息</div></li>' +
	        '<li class="col-xs-4 tab-item" data-tab="order">' +
	        '<div class="tab-content not-current">订单信息</div></li>'+
	      '<li class="col-xs-4 tab-item" data-tab="store">' +
	        '<div class="tab-content not-current">供应商信息</div></li>');
	      break;
	    case 'order':
	      $html = $('<li class="col-xs-6 tab-item" data-tab="order">' +
	        '<div class="tab-content current">订单信息</div></li>' +
	        '<li class="col-xs-6 tab-item" data-tab="store">' +
	        '<div class="tab-content not-current">供应商信息</div></li>');
	      break;
	    case 'product':
	      $html = $('<li class="col-xs-6 tab-item" data-tab="product">' +
	        '<div class="tab-content current">商品信息</div></li>' +
	        '<li class="col-xs-6 tab-item" data-tab="store">' +
	        '<div class="tab-content not-current">供应商信息</div></li>');
	      break;
	    case 'store':
	      $html = $('<li class="col-xs-12 tab-item" data-tab="store">' +
	        '<div class="tab-content current">店铺信息</div></li>');
	      break;
	    default:
	      break;
	  }
	  return $html;
	}




/***/ },
/* 29 */
/***/ function(module, exports, __webpack_require__) {

	/**
	 * Created by Administrator on 2016/8/5.
	 */
	var $ = __webpack_require__(3);
	var Meta = __webpack_require__(12);

	exports.create = function ($parent, tabType, info) {
	  var $clueContent = createContent(tabType,info);
	  $parent.append($clueContent);
	  return new ClueContent($clueContent);
	};


	function ClueContent() {

	}

	ClueContent.prototype.update = function (tabType, chatId) {
	  var $parent = $('.im-content#chat-' + chatId +' .im-clue-content');
	  var $content = $parent.children('.content[data-content="' + tabType +'"]');
	  //如果有该tab对应的内容，则展示，否则ajax请求
	  if ($content.length) {
	    $content.siblings('.content').hide();
	    $parent.find('.loading-icon').hide();
	    $content.show();
	  } else {
	    console.info('没该标签内容', tabType);
	    $parent.find('.content').hide();
	    $parent.find('.loading-icon').show();
	    getContentInfo(tabType, null, Meta.chatId, function (err, info) {
	      if (err) {
	        console.log(err);
	      } else {
	        $parent.find('.loading-icon').hide();
	        var $h = createContent(tabType, info);
	        $parent.append($h);
	      }

	    });
	  }
	};

	function createContent(tabType, info) {
	  var $html;
	  switch (tabType) {
	    case 'inquiry':
	      $html = $('<div class="content" data-content="inquiry">' +
	        '<p class="inquiry-number">询价单：' + info.inquiryId +
	        '</p><p>状态：' + info.status +
	        '</p><p>车辆信息：' + info.vin +
	        '</p><p>车牌：' + info.plateno +
	        '</p><p>车型：' + info.carModel +
	        '</p><p>提交时间：' + info.createdTime +
	        '</p><a href="/agentBuy/inquiryDetail/' + Meta.clueId +
	        '?from=ALL" target="_blank">查看详情&gt;&gt;</a></div>');
	      break;
	    case 'order':
	      $html = $('<div class="content" data-content="order">' +
	        '<p class="orderNumber">订单号：' + info.orderId +
	        '</p><p>状态：' + info.status +
	        '</p><p>店铺：' + info.store +
	        '</p><a href="/orders/viewOrderDetail?orderId=' + Meta.clueId +
	        '&customerServiceUrl=" target="_blank">查看详情&gt;&gt;</a></div>');
	      break;
	    case 'product':
	      $html = $('<div class="content" data-content="product">' +
	        '<p>商品名称：' + info.name +
	        '</p><p>品牌：' + info.brand +
	        '</p><p>零件号：' + info.partNumber +
	        '</p><p>原厂信息：' + info.originalInfo +
	        '</p><p>4s店价：' + (info.fsPrice ? '&yen;'+info.fsPrice : '-') +
	        '</p><a href="/portal/products?productId=' + Meta.clueId +
	        '" target="_blank">查看详情&gt;&gt;</a></div>');
	      break;
	    case 'store':
	      $html = $('<div class="content" data-content="store">' +
	        '<p class="storeName">' + info.name +
	        '</p><p>供应商地址：' + info.address +
	        '</p><p>联系电话： ' + info.telNumber +
	        '</p></div>');
	      break;
	    default:
	      $html = $('<p class="no-data">暂无数据</p>');
	      break;
	  }
	  return $html;
	}

	function makeUrl(tabType, activeChatId) {
	  var url;
	  if (tabType == 'store') {
	    url = '/ec-api/' + tabType + '/' + (activeChatId || Meta.chatId);
	    return url;
	  }
	  url = '/ec-api/' + tabType + '/' + Meta.clueId;
	  return url;
	}

	function getContentInfo(tabType, activeType, activeChatId, callback) {
	  var info = null;
	  var data = {userId: Meta.username};
	  $.ajax({
	    method: 'GET',
	    url: makeUrl(activeType || tabType, activeChatId),
	    data: data,
	    success: function (data) {
	      info = data;
	      callback(null, info);
	    },
	    error: function (error) {
	      console.log(error);
	      callback(error);
	    }
	  });
	}


/***/ },
/* 30 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);
	var html = __webpack_require__(31);
	var $recentContactsTmp = $(html);
	var recentList = __webpack_require__(38);


	exports.create = function ($parent, user) {
	  var $recentContacts = $recentContactsTmp.clone();
	  //在线索信息栏添加tabs
	  // var $clueTabs = clueTabs.create($recentContacts.find('ul.im-clue-tab'), tabType);
	  // var $clueContent = clueContent.create($recentContacts.find('.im-clue-content'), tabType, info);
	  var $recentList = recentList.create($recentContacts.find('.recentPerson'), user);
	  $parent.append($recentContacts);
	  return new RecentContacts($recentList);
	};

	function RecentContacts(recentList) {
	   this.recentList = recentList;
	}


/***/ },
/* 31 */
/***/ function(module, exports) {

	module.exports = "<!--最近联系人列表-->\n<div class=\"im-recent-contact\">\n  <div class=\"recentText\">最近联系人</div>\n  <div class=\"recentPerson\">\n\n  </div>\n</div>\n";

/***/ },
/* 32 */
/***/ function(module, exports, __webpack_require__) {

	var html = __webpack_require__(33);
	var $tabs = $(html);
	$tabs.appendTo('.im-wrap');
	$tabs.find('.im-close').on('click', function () {
	  var leave = confirm('确定要关闭当前所有会话窗口吗？');
	  if (leave) {
	    document.write('窗口无法自动关闭，请自行关闭标签页');
	    window.close();
	  }
	});

	/**
	 * 添加tab
	 * @param {String} chatId 会话ID groupid 或者 luid
	 * @param {String} name 会话名称
	 * @param {String} type 会话类型
	 */
	module.exports.addTab = function (chatId, name, type) {
	  var $tab = $('<a class="im-title normal" href="#">' + name + '</a>');
	  $tab.attr('id', 'tab-chat-' + chatId);
	  if (type) {
	    $tab.attr('data-type', type);
	  }
	  $tab.insertBefore('.im-header .im-close');
	  return $tab;
	};

	/**
	 * 查找该ID下的tab
	 * @param chatId
	 * @returns {*}
	 */
	module.exports.getTab = function (chatId) {
	  return $tabs.find('#tab-chat-' + chatId);
	};

	module.exports.removeTab = function (chatId) {
	  $tabs.find('#tab-chat-' + chatId).remove();
	};

	module.exports.activeTab = function (chatId) {
	  $('#tab-chat-' + chatId).removeClass('normal').addClass('spe')
	    .siblings('.im-title').removeClass('spe').addClass('normal');
	};



/***/ },
/* 33 */
/***/ function(module, exports) {

	module.exports = "<!-- 头部 -->\r\n<div class=\"im-header\">\r\n  <a class=\"im-logo\" href=\"javascript:void(0);\"></a>\r\n  <a class=\"im-close\" href=\"javascript:void(0);\" title=\"关闭\"></a>\r\n</div>\r\n";

/***/ },
/* 34 */
/***/ function(module, exports) {

	/**
	 * Created by Administrator on 2016/6/29.
	 */

	module.exports.resize = function () {
	  var ww = $(window).width();
	  var wh = $(window).height();
	  calcChatSize(ww, wh);
	};

	//初始化窗口大小
	var win_w = $(window).width();
	var win_h = $(window).height();
	var ratio_w = 0.68;
	var ratio_h = 0.88;
	calcChatSize(win_w, win_h);

	//窗口大小自适应
	$(window).resize(function () {
	  var ww = $(window).width();
	  var wh = $(window).height();
	  calcChatSize(ww, wh);
	});

	//窗口大小动态设置
	function calcChatSize(width, height) {
	  $('.im-wrap').css({
	    'width': width * ratio_w + 'px',
	    'margin-left': width * (1 - ratio_w) / 2 + 'px',
	    'margin-top': height * (1 - ratio_h) / 2 + 'px'
	  });
	  $('.im-chat-list').css({'height': (height * ratio_h - 275) + 'px'});
	  $('.im-clue-info').css({'height': (height * ratio_h - 78) + 'px'});
	  $('.im-right-sidebar').css({'height': ($('.im-chat-window').height() + 2) + 'px'});
	  $('.im-view-pic').css({'width': width, 'height': height});
	  var imgs = $('.im-view-pic img');
	  $.each(imgs, function (index, img) {
	    var $img = $(img);
	    var img_w = $img.width();
	    var img_h = $img.height();
	    $img.css({'margin-left': (width - img_w) / 2 + 'px', 'margin-top': (height - img_h) / 2 + 'px'});
	  });
	}


/***/ },
/* 35 */
/***/ function(module, exports, __webpack_require__) {

	var chatPeer = __webpack_require__(11);
	module.exports.ready = function () {
	  var defer = $.Deferred();
	  chatExists(function (exists) {
	    if (exists) {
	      WebIMTabEvent.broadcast('chat.refresh', {target: Meta.chatId, type: Meta.type, clueId: Meta.clueId, search: location.search});
	      document.write('');
	      window.close();
	      return;
	    }

	    WebIMTabEvent.broadcast('chat.created', {target: Meta.chatId, type: Meta.type, clueId: Meta.clueId, search: location.search});
	    defer.resolve();
	  });
	  return defer;
	};

	module.exports.chatExists = chatExists;

	var existsResTime = 0;
	WebIMTabEvent.on('chat.exists', function () {
	  existsResTime = new Date().getTime();
	});

	WebIMTabEvent.on('chat.isexists', function (data) {
	  if (data.target || !window.IMDisconnected) {
	    WebIMTabEvent.broadcast('chat.exists', data);
	  }
	});

	// 收到刷新页面请求，询问用户是否刷新
	WebIMTabEvent.on('chat.refresh', function (data) {
	  console.log('chat.refresh', data);
	  var leave = confirm('已存在聊天窗口，确定离开吗?');
	  if (leave) {
	    location.search = data.search;
	  }
	});

	WebIMTabEvent.on('im.user.changed', function (data) {
	  document.write('<span style="display: none">请关闭窗口</span>');
	  alert('您已切换用户，窗口将关闭，请重新进入会话');
	  window.close();
	});

	function chatExists(callback) {
	  var requestTime = new Date().getTime();
	  WebIMTabEvent.broadcast('chat.isexists', {target: Meta.target, search: location.search});
	  setTimeout(function () {
	    callback(existsResTime >= requestTime);
	  }, 500);
	}


/***/ },
/* 36 */
/***/ function(module, exports, __webpack_require__) {

	var util = __webpack_require__(6);

	module.exports.init = function () {
	  var $imgViewer = $('.im-view-pic');
	  if ($imgViewer.length) {
	    return;
	  }

	  $imgViewer = $('<div class="im-view-pic"><div class="close-btn"></div><div class="prev"></div><div class="next"></div></div>');
	  $imgViewer.appendTo('body');

	  //查看大图,初始化视图窗口
	  $('.im-wrap').on('click', '.message-content img', function () {
	    var curId = $(this).attr('id');
	    var $content = $(this).parents('.im-content');
	    var viewId = 'view-' + $content.attr('id').substr(5);
	    $imgViewer.attr('id', viewId);
	    var imgs = $content.find('.message-content img');
	    var win_w = $(window).width();
	    var win_h = $(window).height();
	    $.each(imgs, function (index, img) {
	      var $img = $(img);
	      var src = $img.attr('src');
	      var id = $img.attr('id');
	      var query = util.parseQuery(src);

	      // 获取图片的实际长宽
	      var imgWidth = query.width;
	      var imgHeight = query.height;

	      if (Image) {
	        var theImage = new Image();
	        theImage.src = $img.attr('src');
	        imgWidth = theImage.width;
	        imgHeight = theImage.height;
	      }

	      if (!imgWidth || !imgHeight) {
	        imgWidth = $img.width();
	        imgHeight = $img.height();
	      }

	      var imgRadio = imgWidth / imgHeight;
	      var winRadio = win_w / win_h;

	      // 最大长宽不能超过屏幕的90%
	      if (imgRadio > winRadio) {
	        imgWidth = imgWidth > win_w * 0.9 ? win_w * 0.9 : imgWidth;
	        imgHeight = imgWidth / imgRadio;
	      } else {
	        imgHeight = imgHeight > win_h * 0.9 ? win_h * 0.9 : imgHeight;
	        imgWidth = imgHeight * imgRadio;
	      }

	      //构造图片元素
	      var $viewImg = $('<img src=' + src + '  id="item-' + id + '">');

	      //图片居中显示
	      $viewImg.css({
	        'margin-left': (win_w - parseInt(imgWidth)) / 2 + 'px',
	        'margin-top': (win_h - parseInt(imgHeight)) / 2 + 'px',
	        'width': imgWidth,
	        'height': imgHeight
	      });

	      //如果与当前点击图片的id相同，则显示，否则隐藏
	      if (id == curId) {
	        $viewImg.css({'display': 'block'});
	      } else {
	        $viewImg.css({'display': 'none'});
	      }
	      $imgViewer.append($viewImg);
	    });

	    //向左向右切换按钮是否展示
	    var $curImg = $imgViewer.find('#item-' + curId);
	    hasPrevOrNext($curImg);

	    //淡入显示大图,回调函数处理左右切换逻辑
	    $imgViewer.fadeIn('normal', 'linear', function () {
	      $('.im-view-pic .prev').on('click', function () {
	        var $prevImg = $curImg.prev('img');
	        $prevImg.show().siblings('img').hide();
	        $curImg = $prevImg;
	        hasPrevOrNext($curImg);
	      });
	      $('.im-view-pic .next').on('click', function () {
	        var $nextImg = $curImg.next('img');
	        $nextImg.show().siblings('img').hide();
	        $curImg = $nextImg;
	        hasPrevOrNext($curImg);
	      });
	    });
	  });

	  //关闭大图展示窗口
	  $('.im-view-pic .close-btn').on('click', function () {
	    $('.im-view-pic img').remove();
	    $('.im-view-pic').hide();
	  });
	};

	//判断大图展示是否有prev，next按钮
	function hasPrevOrNext($ele) {
	  if ($ele.prev('img').length) {
	    $('.im-view-pic .prev').show();
	  } else {
	    $('.im-view-pic .prev').hide();
	  }
	  if ($ele.next('img').length) {
	    $('.im-view-pic .next').show();
	  } else {
	    $('.im-view-pic .next').hide();
	  }
	}


/***/ },
/* 37 */
/***/ function(module, exports, __webpack_require__) {

	var StrategyTypes = __webpack_require__(16).StrategyTypes;
	var OnlineStatus = __webpack_require__(16).OnlineStatus;
	var ServiceType = __webpack_require__(16).ServiceType;

	var allStrategies = {};
	allStrategies[StrategyTypes.ONLINE_RANDOM] = onlineRandom;


	/**
	 * 返回对应策略名称的过滤函数
	 * @param strategyName
	 * @returns {Function}
	 */
	module.exports = function (strategyName) {
	  return allStrategies[strategyName] || allStrategies[StrategyTypes.ONLINE_RANDOM];
	};

	/**
	 * 随机返回在线客服，如果没有在线客服，返回客服主账号
	 * @param store
	 * @param statusList
	 * @returns {*}
	 */
	function onlineRandom(store, statusList) {

	  // 上一次的客服
	  var lastServiceUserId = localStorage.getItem('_serv_of_' + store.storeId);
	  var lastService = null;

	  var services = store.services;
	  console.log('所有客服', services);

	  // 增加在线状态
	  services.forEach(function (service) {
	    for (var i = 0, len = statusList.length; i < len; i++) {
	      var status = statusList[i];
	      if (!status) {
	        continue;
	      }

	      if (status.userId === service.id) {
	        service.online = status.status === OnlineStatus.ONLINE;
	      }
	    }
	  });

	  // 在线客服
	  var resultServices = store.services.filter(function (service) {
	    if (lastServiceUserId === service.id) {
	      lastService = service;
	    }
	    return service.online;
	  });

	  console.log('上一次客服', lastService);

	  // 如果上一次客服在线，选择上一次客服
	  if (lastService && lastService.online) {
	    return lastService;
	  }

	  // 如果没有客服在线，离线消息到主客服
	  if (!resultServices.length) {
	    resultServices = store.services.filter(function (service) {
	      return service.isMaster;
	    });
	  }

	  // 如果没有主客服和在线客服，取所有客服
	  if (!resultServices.length) {
	    resultServices = store.services;
	  }

	  if (!resultServices.length) {
	    return null;
	  }

	  // 随机返回在线账号，如果没有在线账号，随机返回主账号，如果没有主帐号，随机所有帐号
	  var pos = Math.floor(Math.random() * resultServices.length);
	  var result = resultServices[pos];
	  localStorage.setItem('_serv_of_' + store.storeId, result.id);
	  return result;
	}


/***/ },
/* 38 */
/***/ function(module, exports, __webpack_require__) {

	var $ = __webpack_require__(3);


	exports.create = function ($parent, user) {
	 // console.log('user', user);
	  var $recentList = createList(user);
	  $parent.append($recentList);
	  return $recentList;
	};

	function createList(user) {

	}


/***/ }
/******/ ]);